package ar.edu.utn.frba.dds.opendesigners.reservas;

import java.util.ArrayList;
import java.util.List;

import ar.edu.utn.frba.dds.opendesigners.excepciones.ExcepcionReservaAsiento;
import ar.edu.utn.frba.dds.opendesigners.excepciones.ExcepcionReservaError;
import ar.edu.utn.frba.dds.opendesigners.resultados.Asiento;
import ar.edu.utn.frba.dds.opendesigners.user.Usuario;

public class Reservas{

	private static final Reservas INSTANCE = new Reservas();
	private List<Reserva> reservas = new ArrayList<Reserva>();
	
	public static Reservas getInstance(){
		return INSTANCE;
	}
	
	public void reservar(Asiento asiento, Usuario usuario){
		this.agregarReserva(asiento, usuario);
	}
	
	/**
	 * Hace que la reserva que expiro, se le pase al primer usuario que hizo sobre reserva
	 * sobre este asiento
	 */
	public void expiroReserva(Asiento asientoReservado){
		Reserva reserva = this.buscarReserva(asientoReservado);
		try{
			reserva.expiroReserva();
		}catch (ExcepcionReservaAsiento e) {
			this.quitarReserva(asientoReservado);
		}catch (NullPointerException reservaNula) {
			throw new ExcepcionReservaError();
		}
	}
	
	public void expiroReservas(List<Asiento> asientosConReservaExpirada){
		for (Asiento resultadoBusquedaItem : asientosConReservaExpirada) {
			if(this.estaLaReserva(this.buscarReserva(resultadoBusquedaItem)))
				this.expiroReserva(resultadoBusquedaItem);
		}
	}
	
	//Esta se fija si el asiento y numero de vuelo ya existe.
	//La otra CREO que podria llegar a dar un resultado erroneo si existen dos objetos totalmente
	//diferentes pero con los mismos datos. No los detectaria..
	public boolean estaAsientoReservado(Asiento asiento){
		boolean encontrado = false;
		List<Reserva> listaReservas = this.reservas;
		
		int i = 0;
		while(!encontrado && i < listaReservas.size()){
			//Si coinciden numero de vuelo y asiento, ya existe
			if (listaReservas.get(i).getAsiento().getNumeroVuelo().equals(asiento.getNumeroVuelo()) &&
					listaReservas.get(i).getAsiento().getNumeroAsiento().equals(asiento.getNumeroAsiento())){
				encontrado = true;
			}
			i++;
		}
		
		return encontrado;
	}
	
	private void agregarReserva(Asiento asiento, Usuario usuario){
		if(this.estaLaReserva(asiento))
			this.buscarReserva(asiento).agregarSobreReserva(usuario);
		else
			this.reservas.add(new Reserva(asiento, usuario));
	}
	
	private Reserva buscarReserva(Asiento asientoReservado) {
		for (Reserva reserva : this.reservas) {
			if(reserva.getAsiento().equals(asientoReservado))
				return reserva;
		}
		return null;
	}

	public void quitarReserva(Asiento asientoReservado) {
		if(this.estaLaReserva(asientoReservado))
			this.reservas.remove(buscarReserva(asientoReservado));					
	}
	
	private boolean estaLaReserva(Asiento asientoReservado) {
		Reserva reservaBuscada = new Reserva(asientoReservado, null);
		return this.estaLaReserva(reservaBuscada);
	}

	private boolean estaLaReserva(Reserva reserva){
		for (Reserva reservaActual : this.reservas) {
			if(reservaActual.equals(reserva))
				return true;
		}
		return false;
	}
}
